package com.atguigu.gulimall.common;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 1。整合Sentinel
 * gulimall-seckill服务为例
 *  1。导入依赖
 * 		<dependency>
 * 			<groupId>com.alibaba.cloud</groupId>
 * 			<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
 * 		</dependency>
 *  2。下载控制台jar包，启动 	java -jar xxxx —serer.port=xxoo
 *  3。配置sentinel控制台地址信息
 *  4。在控制台调整参数【默认所有的流控制设置保存在内存中，服务重启失效】
 *
 * 2。实时监控图
 *  1。每个模块导入依赖，暴露我们的信息
 *         <dependency>
 *             <groupId>org.springframework.boot</groupId>
 *             <artifactId>spring-boot-starter-actuator</artifactId>
 *         </dependency>
 *    2。并配置
 *    management.endpoints.web.exposure.include=*
 *    3。自定义sentinel流控返回数据
 *    编写配置类SeckillSentinelConfig
 *
 *    4.使用sentinel来保护feign远程调用：熔断；
 *    #A调用B B容易挂，这个feign的开启加在调用方A上面
 *    feign.sentinel.enabled=true
 *
 *    https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
 *      Sentinel 适配了 Feign 组件。如果想使用，除了引入 spring-cloud-starter-alibaba-sentinel 的依赖外还需要 2 个步骤：
 *      配置文件打开 Sentinel 对 Feign 的支持：feign.sentinel.enabled=true
 *      加入 spring-cloud-starter-openfeign 依赖使 Sentinel starter 中的自动化配置类生效：
 *      <dependency>
 *          <groupId>org.springframework.cloud</groupId>
 *          <artifactId>spring-cloud-starter-openfeign</artifactId>
 *      </dependency>
 *
 *      5.在调用方的Feign接口中设置熔断降级方法
 *
 *      6。远程服务方降级：
 *          场景：超大流量时，必须牺牲一些远程服务，在服务的提供方（远程服务）指定降级策略
 *          提供方时在运行状态的，但是不运行自己的业务逻辑，返回的时默认的降级数据（限流的数据）
 *
 *          熔断数据在调用方，降级数据在提供方
 *
 *      7。自定义受保护的资源
 *      1。基于代码：
 *      try(Entry entry = SphU.entry("currentSeckillSkus")){
 *              //。。。。。。
 *      } catch (BlockException e) {
 *             log.info("限流后处理.....");
 *             e.printStackTrace();
 *      }
 *
 *      2。基于注解
 *          @SentinelResource(value = "getCurrentSeckillSkusResource",blockHandler = "blockHandler",fallback = "fallback")
 *          blockHandler指定的方法要和原方法在同一个类中
 *          限流后走blockHandler指定的方法，blockHandler指定的方法要与原方法有相同的返回值，相同的参数，可以多一个BlockException
 *
 *          fallback可写在别的类中，如果在别但类中，方法必须是static类型 fallbackClass指定类名
 *          fallback异常是被调用，返回值必须和原方法一直，参数也要一致，可以多一个Throwable类型的参数
 *
 *      public List<SeckillSkuRedisTo> blockHandler(BlockException e){
 *         log.error("getCurrentSeckillSkus被限流了");
 *         return null;
 *     }
 *      blockHandler会在原方法被限流/降级/系统保护是被调用
 *      而 fallback 会在针对所有类型的异常是被调用
 *
 *      无论是1 2方式，一定要配置被限流以后的默认返回，在catch或blockHandler方法中
 *      url请求可以是指统一放回 秒杀系统的SeckillSentinelConfig里面有配置
 *
 */

@SpringBootApplication
public class GulimallCommonApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallCommonApplication.class, args);
    }

}
